﻿using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Text;

namespace UnityEngine.UI
{
    /// <summary>
    /// 树控件节点
    /// </summary>
    public class TreeNode : TreeNodeContainer, IPointerClickHandler
    {
        public const string TextKey = "text";
        public const string RetractKey = "retract";
        public const string ActiveKey = "active";//默认false
        public const string ChildNormalColorKey = "childNormalColor";//#FF0000FF(红色) 
        public const string ChildSelectColorKey = "childSelectColor";

        /// <summary>
        /// 子节点展开开关
        /// </summary>
        [SerializeField]
        private Toggle m_toggleChildSwitch;
        /// <summary>
        /// 子节点展开开关占位
        /// 可选
        /// </summary>
        [SerializeField]
        private GameObject m_childSwitchPlaceHolder;
        [SerializeField]
        private Toggle m_toggleItem;
        /// <summary>
        /// 活动属性
        /// active设置是否显示
        /// </summary>
        [SerializeField]
        private GameObject m_goActiveItem;
        /// <summary>
        /// 文字显示
        /// </summary>
        [SerializeField]
        private Text m_textItem;
        /// <summary>
        /// 节点总垂直布局
        /// </summary>
        [SerializeField]
        private VerticalLayoutGroup m_nodeGroup;
        /// <summary>
        /// 节点item水平布局
        /// </summary>
        [SerializeField]
        private HorizontalLayoutGroup m_itemContainerGroup;

        /// <summary>
        /// 用户信息附着的信息
        /// </summary>
        private Dictionary<string, string> m_userParamsDic;

        /// <summary>
        /// 所属树控件
        /// </summary>
        private TreeView m_ownerView;
        /// <summary>
        /// 父节点
        /// </summary>
        private TreeNode m_parentNode;
        /// <summary>
        /// 子节点缩进
        /// </summary>
        private int m_childRetract = 20;

        public int ChildRetract
        {
            get
            {
                return m_childRetract;
            }
            set
            {
                if(m_childRetract != value)
                {
                    m_childRetract = value;
                    UpdateChildRetract();
                }
            }
        }

        public string ItemText
        {
            get
            {
                return GetParam(TextKey);
            }
        }

        /// <summary>
        /// 是否展开了子节点
        /// </summary>
        private bool ChildExpanded
        {
            get
            {
                return m_toggleChildSwitch && m_toggleChildSwitch.isOn;
            }
        }
        
        public override RectTransform ContainerRoot
        {
            get
            {
                return TransCached;
            }
        }

        public override TreeView OwnerView
        {
            get
            {
                return m_ownerView;
            }
        }

        public bool IsRoot
        {
            get
            {
                return m_parentNode == null;
            }
        }

        /// <summary>
        /// 获取当前node常规时的字体颜色
        /// </summary>
        public string NormalTextItemColorStr
        {
            get
            {
                string str;
                if(m_parentNode != null && m_parentNode.TryGetParam(ChildNormalColorKey, out str))
                {
                    return str;
                }
                return ToRichTextColorStr(m_ownerView ? m_ownerView.NormalTextItemColor : Color.white);
            }
        }

        /// <summary>
        /// 获取当前node选择时的字体颜色
        /// </summary>
        public string SelectTextItemColorStr
        {
            get
            {
                string str;
                if(m_parentNode != null && m_parentNode.TryGetParam(ChildSelectColorKey, out str))
                {
                    return str;
                }
                return ToRichTextColorStr(m_ownerView ? m_ownerView.SelectTextItemColor : Color.green);
            }
        }

        /// <summary>
        /// 开关Node
        /// </summary>
        public event System.Action<TreeNode, bool> OnSwitchNode;
        /// <summary>
        /// 改变选择的node
        /// </summary>
        public event System.Action<TreeNode, bool> OnChangeSelectNode;

        protected override void Awake()
        {
            base.Awake();
            UpdateChildSwitchState();
            if(m_toggleChildSwitch)
            {
                m_toggleChildSwitch.onValueChanged.AddListener(OnChildSwitchStateChanged);
            }
            if(m_toggleItem)
            {
                m_toggleItem.onValueChanged.AddListener(OnToggleItemChanged);
            }
        }

        protected override void OnDisable()
        {
            base.OnDisable();
            if(m_toggleItem && m_toggleItem.isOn)
            {
                m_toggleItem.isOn = false;
            }
        }

        /// <summary>
        /// 节点创建时调用
        /// </summary>
        public void OnGenerate()
        {
            ActiveGo(false);
        }

        /// <summary>
        /// 更新
        /// </summary>
        private void UpdateChildSwitchState()
        {
            if(m_toggleChildSwitch)
            {
                m_toggleChildSwitch.gameObject.SetActive(HasChild);
                if(m_childSwitchPlaceHolder)
                {
                    m_childSwitchPlaceHolder.SetActive(!HasChild);
                }
            }
        }

        /// <summary>
        /// 更新展开开关的原sprite
        /// </summary>
        private void UpdateChildSwitchSprite(bool value)
        {
            if(m_toggleChildSwitch)
            {
                var graphic = m_toggleChildSwitch.GetComponent<Graphic>();
                if(graphic)
                {
                    graphic.CrossFadeAlpha(value ? 0 : 1, 0.1f, true);
                }
            }
        }

        private void OnChildSwitchStateChanged(bool value)
        {
            UpdateChildSwitchSprite(value);
            ActiveChildNodes(value);
            if(m_ownerView)
            {
                m_ownerView.CallTreeNodeSwitch(this, value);
            }
            if(OnSwitchNode != null)
            {
                OnSwitchNode.Invoke(this, value);
            }
        }

        private void OnToggleItemChanged(bool value)
        {
            UpdateTextItem(value);
            if(m_ownerView != null)
            {
                m_ownerView.CallTreeNodeSelect(this, value);
            }
            if(OnChangeSelectNode != null)
            {
                OnChangeSelectNode(this, value);
            }
        }

        /// <summary>
        /// 更新Text颜色
        /// </summary>
        /// <param name="select"></param>
        private void UpdateTextItem(bool select)
        {
            if(m_textItem)
            {
                m_textItem.text = string.Format(
                    "<color={0}>{1}</color>",
                    select ? SelectTextItemColorStr : NormalTextItemColorStr,
                    ItemText);
            }
        }

        private void UpdateChildRetract()
        {
            if(!m_nodeGroup)
            {
                m_nodeGroup = GoCached.GetComponent<VerticalLayoutGroup>();
                if(!m_nodeGroup)
                {
                    m_nodeGroup = GoCached.AddComponent<VerticalLayoutGroup>();
                    m_nodeGroup.childForceExpandHeight = false;
                    m_nodeGroup.childForceExpandWidth = false;
                }
            }
            if(m_nodeGroup)
            {
                var padding = m_nodeGroup.padding;
                padding.left = m_childRetract;
                m_nodeGroup.padding = padding;
            }
            if(!m_itemContainerGroup)
            {
                m_itemContainerGroup = GoCached.GetComponentInChildren<HorizontalLayoutGroup>();
            }
            if(m_itemContainerGroup)
            {
                var padding = m_itemContainerGroup.padding;
                padding.left = -m_childRetract;
                m_itemContainerGroup.padding = padding;
            }
        }

        /// <summary>
        /// 设置view
        /// </summary>
        /// <param name="view"></param>
        public void SetOwnerView(TreeView view)
        {
            m_ownerView = view;
            if(m_toggleItem)
            {
                m_toggleItem.group = view.NodeToggleGroup;
            }
        }

        /// <summary>
        /// 设置item显示文字
        /// </summary>
        /// <param name="text"></param>
        public void SetText(string text)
        {
            if(m_textItem)
            {
                m_textItem.text = text;
            }
        }

        /// <summary>
        /// 设置活动物体显示/隐藏
        /// </summary>
        /// <param name="active"></param>
        public void ActiveGo(bool active)
        {
            if(m_goActiveItem)
            {
                m_goActiveItem.SetActive(active);
            }
        }

        protected TreeNode InsertBrotherNode(int deltaIndex)
        {
            SortedList<TreeNode, byte> brotherList = null;
            if(IsRoot)
            {
                brotherList = OwnerView.ChildList;
            }
            else
            {
                brotherList = m_parentNode.ChildList;
            }
            return InsertChildNodeAt(brotherList.IndexOfKey(this) + deltaIndex);
        }

        /// <summary>
        /// 在此节点前加一个节点
        /// </summary>
        /// <returns></returns>
        public TreeNode AddBeforeNode()
        {
            return InsertBrotherNode(0);
        }

        /// <summary>
        /// 在此节点后加一个节点
        /// </summary>
        /// <returns></returns>
        public TreeNode AddAffterNode()
        {
            return InsertBrotherNode(1);
        }

        protected override void AddNodeToList(TreeNode node)
        {
            if(!HasChild)
            {
                UpdateChildRetract();
            }
            base.AddNodeToList(node);
            node.m_parentNode = this;
            UpdateChildSwitchState();
        }

        protected override void RemoveNodeFromList(TreeNode node, int index)
        {
            base.RemoveNodeFromList(node, index);
            UpdateChildSwitchState();
        }

        public void ActiveChildNodes(bool active)
        {
            if(HasChild)
            {
                foreach(var item in ChildList.Keys)
                {
                    item.ActiveNode(active);
                }
            }
        }

        public void ActiveNode(bool active)
        {
            GoCached.SetActive(active);
        }

        public void OnPointerClick(PointerEventData eventData)
        {
            if(eventData.clickCount == 2)
            {
                if(m_toggleChildSwitch && HasChild)
                {
                    m_toggleChildSwitch.isOn = !m_toggleChildSwitch.isOn;
                }
            }
        }

        /// <summary>
        /// 开始设置参数
        /// </summary>
        public void OnBeginSetParam()
        {
        }

        /// <summary>
        /// 设置所有param完成
        /// </summary>
        public void OnSetAllParam()
        {
            UpdateTextItem(false);
        }

        /// <summary>
        /// 设置参数
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void SetParam(string key, string value)
        {
            if(m_userParamsDic == null)
            {
                m_userParamsDic = new Dictionary<string, string>();
            }
            m_userParamsDic[key] = value;
            if(TextKey.Equals(key, StringComparison.OrdinalIgnoreCase))
            {
                SetText(value);
            }
            else if(RetractKey.Equals(key, StringComparison.OrdinalIgnoreCase))
            {
                int retract;
                if(int.TryParse(value, out retract))
                {
                    ChildRetract = retract;
                }
            }
            else if(ActiveKey.Equals(key, StringComparison.OrdinalIgnoreCase))
            {
                bool boolValue = false;
                if(bool.TryParse(value, out boolValue))
                {
                    ActiveGo(boolValue);
                }
            }
        }

        /// <summary>
        /// 尝试获取key对应的value字符串
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>false为获取失败</returns>
        public bool TryGetParam(string key, out string value)
        {
            if(!string.IsNullOrEmpty(key))
            {
                if(m_userParamsDic != null)
                {
                    return m_userParamsDic.TryGetValue(key, out value);
                }
            }
            value = null;
            return false;
        }

        /// <summary>
        /// 根据key获取参数值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string GetParam(string key)
        {
            string value = null;
            if(!string.IsNullOrEmpty(key))
            {
                if(m_userParamsDic != null)
                {
                    m_userParamsDic.TryGetValue(key, out value);
                }
            }
            return value;
        }

        /// <summary>
        /// 是否存在key的参数
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool HasParam(string key)
        {
            return !string.IsNullOrEmpty(key) &&
                m_userParamsDic != null &&
                m_userParamsDic.ContainsKey(key);
        }

        /// <summary>
        /// 尝试获取参数的int形式
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool TryGetIntParam(string key, out int value)
        {
            string strValue;
            if(TryGetParam(key, out strValue))
            {
                if(!string.IsNullOrEmpty(strValue))
                {
                    return int.TryParse(strValue, out value);
                }
            }
            value = 0;
            return false;
        }

        /// <summary>
        /// 尝试获取参数的bool 形式
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool TryGetBoolParam(string key, out bool value)
        {
            string strValue;
            if(TryGetParam(key, out strValue))
            {
                if(!string.IsNullOrEmpty(strValue))
                {
                    return bool.TryParse(strValue, out value);
                }
            }
            value = false;
            return false;
        }


        /// <summary>
        /// 颜色转#FFFFFFFF十六进制格式
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        public static string ToRichTextColorStr(Color color)
        {
            return ToRichTextColorStr(((Color32)color));
        }

        /// <summary>
        /// 颜色转#FFFFFFFF十六进制格式
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        public static string ToRichTextColorStr(Color32 color)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append('#');
            sb.Append(color.r.ToString("x2"));
            sb.Append(color.g.ToString("x2"));
            sb.Append(color.b.ToString("x2"));
            sb.Append(color.a.ToString("x2"));
            return sb.ToString();
        }
    }
}